package com.yuncheng.oaApi.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import javax.annotation.Resource;

import com.yuncheng.oaApi.constant.OaCommonFlowConstant;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.oaApi.constant.NkConstant;
import com.yuncheng.oaApi.entity.*;
import com.yuncheng.oaApi.mapper.OaSysRoleMapper;
import com.yuncheng.oaApi.service.*;
import com.yuncheng.utils.ThreadContextHelper;
import com.yuncheng.vo.CurrentUserVo;
import com.yuncheng.vo.HttpResult;
import com.yuncheng.annotation.AutoLog;
import com.yuncheng.utils.I18nUtil;
import com.yuncheng.common.base.controller.BaseController;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import utils.DateConversionUtils;

/**
 * @Description: 内控-项目预算指标表
 * @Author: lhb
 * @Date: 2023-11-20
 * @Version: V1.0
 */
@Api(tags = "NK_内控-项目预算指标表接口")
@RestController
@RequestMapping("/api/spzx-oa/nkRsXmyszbb")
public class NkRsXmyszbbController extends BaseController<NkRsXmyszbb, INkRsXmyszbbService> {

    private static final Logger log = LoggerFactory.getLogger(NkRsXmyszbbController.class);

    @Resource
    private INkRsXmyszbbService nkRsXmyszbbService;

    @Resource
    @Lazy
    private INkRsYszbtzService nkRsYszbtzService;

    @Resource
    @Lazy
    private INkRsYszbczjlService nkRsYszbczjlService;

    @Resource
    @Lazy
    private IOaSysRoleService sysRoleService;


    @Resource
    @Lazy
    private OaSysRoleMapper oaSysRoleMapper;

    @Resource
    @Lazy
    private INkRsNdService nkRsNdService;




    /**
     * 分页列表查询
     *
     * @param nkRsXmyszbb
     * @param pageNo
     * @param pageSize
     * @param
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-只查询当前登陆人下部门-分页列表查询")
    @ApiOperation(value = "内控-项目预算指标表-只查询当前登陆人下部门-分页列表查询")
    @GetMapping(value = "/list")
    public HttpResult<?> queryPageList(NkRsXmyszbb nkRsXmyszbb,
                                       @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        CurrentUserVo user = ThreadContextHelper.getCurrentUser(); //获取当前登陆人

        LambdaQueryWrapper<NkRsXmyszbb> queryWrapper = new LambdaQueryWrapper<>();
        Page<NkRsXmyszbb> page = new Page<>(pageNo, pageSize);
        IPage<NkRsXmyszbb> pageList = null;

        //预算项目要名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFysxmmc()),NkRsXmyszbb::getFysxmmc,nkRsXmyszbb.getFysxmmc());
        //指标摘要
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFzbzy()),NkRsXmyszbb::getFzbzy,nkRsXmyszbb.getFzbzy());
        //部门名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFbm()),NkRsXmyszbb::getFbm,nkRsXmyszbb.getFbm());
        //年度
//        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFnd()),NkRsXmyszbb::getFnd,nkRsXmyszbb.getFnd());
        //政府经济分类名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFzfjjflmc()),NkRsXmyszbb::getFzfjjflmc,nkRsXmyszbb.getFzfjjflmc());
        //部门经济分类编码
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFbmjjflbm()),NkRsXmyszbb::getFbmjjflbm,nkRsXmyszbb.getFbmjjflbm());
        //部门经济分类名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFbmjjflmc()),NkRsXmyszbb::getFbmjjflmc,nkRsXmyszbb.getFbmjjflmc());
        //
        List<NkRsnd> nkRsnds = nkRsNdService.list(new LambdaQueryWrapper<NkRsnd>()
                .eq(NkRsnd::getFsfxz, OaCommonFlowConstant.NDXZ_YES));

        if (CollectionUtils.isNotEmpty(nkRsnds)){
            queryWrapper.like(NkRsXmyszbb::getFnd,nkRsnds.get(0).getFnd());
        }else {
            queryWrapper.like(NkRsXmyszbb::getFnd,DateConversionUtils.DateToYear(new Date()));
        }


        queryWrapper.orderByAsc(NkRsXmyszbb::getCreateTime);
        //查询角色为财务的用户

        List<OaSysRole> oaSysRoles = sysRoleService.list(new LambdaQueryWrapper<OaSysRole>()
                .eq(OaSysRole::getRoleName, NkConstant.ROLE_NAME_CW));


        List list = new ArrayList();

        if (CollectionUtils.isNotEmpty(oaSysRoles)){

            List<OaSysUserRole> CWlist = oaSysRoleMapper.cwList();

            if (CollectionUtils.isNotEmpty(CWlist)){
                //循环这个list
                for (OaSysUserRole cw : CWlist){
                    list.add(cw.getUserId());
                }
                boolean exists = list.contains(user.getId());
                if (exists){
                    pageList =  nkRsXmyszbbService.page(page, queryWrapper);
                    return HttpResult.ok(pageList);
                }else {
                    //部门id 只查询当前部门拆分的项目预算指标
                    String deptId = user.getDeptId();
                    queryWrapper.like(NkRsXmyszbb::getFbmid,deptId);
                    pageList = nkRsXmyszbbService.page(page, queryWrapper);
                    return HttpResult.ok(pageList);
                }

            }

        }

        return HttpResult.ok(pageList);
    }

    /**
     * 分页列表查询
     *
     * @param nkRsXmyszbb
     * @param pageNo
     * @param pageSize
     * @param
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-所有-分页列表查询")
    @ApiOperation(value = "内控-项目预算指标表-所有-分页列表查询")
    @GetMapping(value = "/lists")
    public HttpResult<?> queryPageLists(NkRsXmyszbb nkRsXmyszbb,
                                        @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        LambdaQueryWrapper<NkRsXmyszbb> queryWrapper = new LambdaQueryWrapper<>();




        //预算项目要名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFysxmmc()), NkRsXmyszbb::getFysxmmc,nkRsXmyszbb.getFysxmmc());
        //指标摘要
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFzbzy()), NkRsXmyszbb::getFzbzy,nkRsXmyszbb.getFzbzy());
        //部门
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFbm()), NkRsXmyszbb::getFbm, nkRsXmyszbb.getFbm());

        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFyszbzt()), NkRsXmyszbb::getFyszbzt, nkRsXmyszbb.getFyszbzt());

        //总指标
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFzzb()), NkRsXmyszbb::getFzzb, nkRsXmyszbb.getFzzb());

        //部门经济分类
        queryWrapper.like(StringUtils.isNotBlank(nkRsXmyszbb.getFbmjjflmc()), NkRsXmyszbb::getFbmjjflmc, nkRsXmyszbb.getFbmjjflmc());


        List<NkRsnd> nkRsnds = nkRsNdService.list(new LambdaQueryWrapper<NkRsnd>()
                .eq(NkRsnd::getFsfxz, OaCommonFlowConstant.NDXZ_YES));

        if (CollectionUtils.isNotEmpty(nkRsnds)){
            queryWrapper.like(NkRsXmyszbb::getFnd,nkRsnds.get(0).getFnd());
        }else {
            queryWrapper.like(NkRsXmyszbb::getFnd,DateConversionUtils.DateToYear(new Date()));
        }

//        //年度
//        //如果年度为空 默认年度为当前年度，如果不为空 在查
//        if(StringUtils.isNotBlank(nkRsXmyszbb.getFnd())){
//            queryWrapper.like(NkRsXmyszbb::getFnd,nkRsXmyszbb.getFnd());
//        }else {
//            queryWrapper.like(NkRsXmyszbb::getFnd, DateConversionUtils.DateToYear(new Date()));
//        }




        queryWrapper.orderByAsc(NkRsXmyszbb::getCreateTime);
        Page<NkRsXmyszbb> page = new Page<>(pageNo, pageSize);
        IPage<NkRsXmyszbb> pageList = nkRsXmyszbbService.page(page, queryWrapper);

        return HttpResult.ok(pageList);
    }


    /**
     * 添加
     *
     * @param nkRsXmyszbb
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-添加")
    @ApiOperation(value = "内控-项目预算指标表-添加")
    @PostMapping(value = "/add")
    public HttpResult<?> add(@RequestBody NkRsXmyszbb nkRsXmyszbb) {
        HttpResult<String> result = new HttpResult(true);


        nkRsXmyszbbService.save(nkRsXmyszbb);
        result.setResult(nkRsXmyszbb.getId());
        result.setMessage(I18nUtil.message("save.success"));
        return result;
    }

    /**
     * 编辑
     *
     * @param nkRsXmyszbb
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-编辑")
    @ApiOperation(value = "内控-项目预算指标表-编辑")
    @PutMapping(value = "/edit")
    public HttpResult<?> edit(@RequestBody NkRsXmyszbb nkRsXmyszbb) {
        //如果预算指标状态为收回 则删除 这条记录 并将 数据 还给台账记录

        if (nkRsXmyszbb.getFyszbzt().equals(NkConstant.ZBZT_SH)){
            //如果已支付金额不为0 或者 空 ，则代表已经有支出 就不能 收回
//            if (StringUtils.isNotBlank(nkRsXmyszbb.getFyzfje()) || nkRsXmyszbb.getFyzfje().equals("0.00")){
//                throw new BusinessException("当前项目预算指标已有支出，无法收回");
//            }
            String ftzid = nkRsXmyszbb.getFtzid();
            //获取预算指标台账
            NkRsYszbtz nkRsYszbtz = nkRsYszbtzService.getById(ftzid);
            //获取台账的原本的 已申请支付金额，已支付金额，指标结余
            BigDecimal tzzzb = new BigDecimal(nkRsYszbtz.getFzzb()); //总指标
            BigDecimal tzysqzfje = new BigDecimal(nkRsYszbtz.getFysqzfje());//已申请支付金额
            BigDecimal tzyzfje = new BigDecimal(nkRsYszbtz.getFyzfje());//已支付金额
            BigDecimal tzzbzy = new BigDecimal(nkRsYszbtz.getFzbjy());//指标结余

            //获取本条记录的指标结余
            BigDecimal yszbjy = new BigDecimal(nkRsXmyszbb.getFzbzy());

            //将 预算指标的指标结余 加上 台帐的指标结余 获取新的指标结余
            BigDecimal newzbjy = yszbjy.add(tzzbzy);// 新的指标结余
            //将已申请支付金额 和 已支付金额 加 预算指标结余 获取新的已申请支付金额 和 已支付金额
            BigDecimal newysqzfje = tzysqzfje.add(yszbjy);
            BigDecimal newyzfje = tzyzfje.add(yszbjy);
            //重新计算支出进度
            BigDecimal newtzzzd = newyzfje.divide(tzzzb, 3, BigDecimal.ROUND_HALF_UP);

            nkRsYszbtz.setFysqzfje(String.valueOf(newysqzfje));
            nkRsYszbtz.setFyzfje(String.valueOf(newyzfje));
            nkRsYszbtz.setFzbjy(String.valueOf(newzbjy));
            nkRsYszbtz.setFzcjd(String.valueOf(newtzzzd));
            //更新台账
            nkRsYszbtzService.updateById(nkRsYszbtz);

            String zy = "";
            zy += Optional.ofNullable(nkRsYszbtz.getFysxmmc()).orElseGet(()->"");
            zy += "/";
            zy += "总指标["+Optional.ofNullable(nkRsYszbtz.getFzzb()).orElseGet(()->"0")+"]";
            zy += "/";
            zy += "指标结余["+Optional.ofNullable(nkRsYszbtz.getFzbjy()).orElseGet(()->"0")+"]";

            //添加操作记录
            nkRsYszbczjlService.addczjl(NkConstant.ZBZT_SH, ftzid, zy, NkConstant.SZLX_SR,nkRsXmyszbb.getFzzb(),nkRsXmyszbb.getId(),nkRsXmyszbb.getFtzid());
            //然后删除项目预算指标
            nkRsXmyszbbService.removeById(nkRsXmyszbb);
        }

        nkRsXmyszbbService.updateById(nkRsXmyszbb);
        return HttpResult.ok(I18nUtil.message("update.success"));
    }


    @AutoLog(value = "内控-项目预算指标表-通过id获取操作记录")
    @ApiOperation(value = "内控-项目预算指标表-通过id获取操作记录")
    @GetMapping(value = "/getIdByczjl")
    public HttpResult<?> getIdByczjl(String id, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                     String fyszbmc,String fczr,String fczbm,String fbmzcjjfl){
        LambdaQueryWrapper<NkRsYszbczjl> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NkRsYszbczjl::getFyszbid ,id);

        Page<NkRsYszbczjl> page = new Page<>(pageNo, pageSize);
        IPage<NkRsYszbczjl> pageList = nkRsYszbczjlService.page(page, queryWrapper);
        return HttpResult.ok(pageList);

    }




    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-通过id删除")
    @ApiOperation(value = "内控-项目预算指标表-通过id删除")
    @DeleteMapping(value = "/delete")
    public HttpResult<?> delete(@RequestParam("id") String id) {
        nkRsXmyszbbService.removeById(id);
        return HttpResult.ok(I18nUtil.message("delete.success"));
    }

    /**
     * 通过id批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-批量删除")
    @ApiOperation(value = "内控-项目预算指标表-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public HttpResult<?> deleteBatch(@RequestParam("ids") String ids) {
        nkRsXmyszbbService.removeByIds(Arrays.asList(ids.split(",")));
        return HttpResult.ok(I18nUtil.message("delete.success"));
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "内控-项目预算指标表-通过id查询")
    @ApiOperation(value = "内控-项目预算指标表-通过id查询")
    @GetMapping(value = "/queryById")
    public HttpResult<?> queryById(@RequestParam("id") String id) {
        NkRsXmyszbb nkRsXmyszbb = nkRsXmyszbbService.getById(id);
        return HttpResult.ok(nkRsXmyszbb);
    }


    /**
     * 部门预算指标进度
     */
    @AutoLog(value = "内控-预算指标台账-部门预算指标进度/部门预算指标进度")
    @ApiOperation(value = "内控-部门预算指标进度")
    @GetMapping(value = "/bmzbJd")
    public HttpResult<?> bmzbJd(String ids,String nd){

        if (StringUtils.isBlank(nd)){
            nd = DateConversionUtils.DateToYear(new Date());
        }

        Map zjdmap = new HashMap<>();
        Map pagejdmap = new HashMap<>();
        List jdlist = new ArrayList<>();

        List<NkRsXmyszbb> nkRsXmyszbbList = nkRsXmyszbbService.list(new LambdaQueryWrapper<NkRsXmyszbb>()
                .eq(NkRsXmyszbb::getFnd, nd));


        if (CollectionUtils.isNotEmpty(nkRsXmyszbbList)){
            BigDecimal fzzb = new BigDecimal(0);
            BigDecimal fyzfje = new BigDecimal(0);
            BigDecimal fzbjy = new BigDecimal(0);
//            BigDecimal fzcjd = new BigDecimal(0);


            for (NkRsXmyszbb nkRsXmyszbb : nkRsXmyszbbList) {
                fzzb = fzzb.add((new BigDecimal(nkRsXmyszbb.getFzzb())));
                fyzfje = fyzfje.add(new BigDecimal(nkRsXmyszbb.getFyzfje()));
                fzbjy = fzbjy.add(new BigDecimal(nkRsXmyszbb.getFzbjy()));
            }
            BigDecimal percentage = fyzfje.divide(fzzb, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            // 检查小数部分是否为零，如果为零则返回整数部分
            if (percentage.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                percentage = percentage.setScale(0, RoundingMode.DOWN);
            } else {
                percentage = percentage.setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            String percentageString = percentage.toPlainString() + "%";

            zjdmap.put("fzzb",fzzb);
            zjdmap.put("fyzfje",fyzfje);
            zjdmap.put("fzbjy",fzbjy);
            zjdmap.put("fzcjd",percentageString);

        }

        if (StringUtils.isNotBlank(ids)){
            BigDecimal fzzb = new BigDecimal(0);
            BigDecimal fyzfje = new BigDecimal(0);
            BigDecimal fzbjy = new BigDecimal(0);
//            BigDecimal fzcjd = new BigDecimal(0);

            List<String> pagelists = Arrays.asList(ids.split(",|，"));
            List<NkRsXmyszbb> rsYszbtzLists = nkRsXmyszbbService.listByIds(pagelists);
            for (NkRsXmyszbb rsYszbtzList:rsYszbtzLists){
                fzzb = fzzb.add((new BigDecimal(rsYszbtzList.getFzzb())));
                fyzfje = fyzfje.add(new BigDecimal(rsYszbtzList.getFyzfje()));
                fzbjy = fzbjy.add(new BigDecimal(rsYszbtzList.getFzbjy()));
            }
            // 计算百分比，保留四位小数
            BigDecimal percentage = fyzfje.divide(fzzb, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            // 检查小数部分是否为零，如果为零则返回整数部分
            if (percentage.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                percentage = percentage.setScale(0, RoundingMode.DOWN);
            } else {
                percentage = percentage.setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            String percentageString = percentage.toPlainString() + "%";


            pagejdmap.put("fzzb",fzzb);
            pagejdmap.put("fyzfje",fyzfje);
            pagejdmap.put("fzbjy",fzbjy);
            pagejdmap.put("fzcjd",percentageString);


        }

        jdlist.add(zjdmap);
        jdlist.add(pagejdmap);


        return HttpResult.ok(jdlist);
    }











}
